# include "widgetLienzoqt.h"

void 
WidgetLienzoQT::Guardar()
{
	ofstream fichero;
	
	fichero.open(nombre.c_str(), ios::out);
	
	if (fichero.is_open())
	{
		fichero << lienzo->Texto();
	}
	
	fichero.close();
}

void
WidgetLienzoQT::GuardarComo()
{
	ofstream fichero;
	
	QString fn = QFileDialog::getSaveFileName(QString::null, QString::null, this);
	
	if (!fn.isEmpty())
	{
		string aux = fn;
		
		nombre = aux;
		
		Guardar();
	}
}

void
WidgetLienzoQT::Abrir()
{
	QString fn = QFileDialog::getOpenFileName(QString::null, QString::null, this);
	
	if (!fn.isEmpty())
	{
		lienzo->leerFichero(fn);
		
		actualizar();
	}
}

void 
WidgetLienzoQT::cambiaColor ()
{
	for (list<Figura*>::iterator i = seleccionadas.begin(); i != seleccionadas.end(); i++)
	{
		(*i)->setCR(sliderR->value());
		
		(*i)->setCG(sliderG->value());
		
		(*i)->setCB(sliderB->value());
	}
	
	update();
}

void 
WidgetLienzoQT::desagrupaEvento ()
{
	for (list<Figura*>::iterator i = seleccionadas.begin(); i != seleccionadas.end(); i++)
	{
		if (dynamic_cast <Grupo*>(*i))
		{
			lienzo->desagrupar((Grupo*)(*i));
		}
	}
	
	seleccionadas.clear();
}

void 
WidgetLienzoQT::agrupaEvento () 
{
	Grupo* aux;
	
	if (!seleccionadas.empty())
	{
		aux = lienzo->agrupar(seleccionadas); 
		
		seleccionadas.clear();
		
		seleccionadas.push_back(aux);
		
		update();
	}
};

void 
WidgetLienzoQT::borraEvento ()
{
	for (list<Figura*>::iterator i = seleccionadas.begin(); i != seleccionadas.end(); i++)
	{
		lienzo->quitarFigura (*i);
	}
	
	seleccionadas.clear();
	
	actualizar();
}

void 
WidgetLienzoQT::copiaEvento ()
{
	for (list<Figura*>::iterator i = portaPapeles.begin(); i != portaPapeles.end(); i++)
	{
		delete (*i);	
	}
	
	portaPapeles.clear();
	
	for (list<Figura*>::iterator i = seleccionadas.begin(); i != seleccionadas.end(); i++)
	{
		Figura* clon = (*i)->clonar();
		
		portaPapeles.push_back(clon);
	}
	
	actualizar();
}

void 
WidgetLienzoQT::cortaEvento ()
{
	copiaEvento();
	
	for (list<Figura*>::iterator i = seleccionadas.begin(); i != seleccionadas.end(); i++)
	{
		lienzo->quitarFigura (*i);
	}
	
	seleccionadas.clear();
	
	actualizar();
}

void 
WidgetLienzoQT::pegaEvento ()
{	
	list<Figura*> aux;
	
	for (list<Figura*>::iterator i = portaPapeles.begin(); i != portaPapeles.end(); i++)
	{
		lienzo->anyadirFigura (*i);	
		
		aux.push_back((*i)->clonar());
	}
	
	portaPapeles = aux;
	
	actualizar();
}

void
WidgetLienzoQT::actualizar()
{
	update();
}

void 
WidgetLienzoQT::paintEvent( QPaintEvent *)
{
	QPainter paint(this);
	
	QPoint a, b;
	
	list<Figura*>l;
	
	Figura* f;
	
	if (!seleccionadas.empty())
	{
		f = new Grupo();
		
		for (list<Figura*>::iterator i = seleccionadas.begin(); i != seleccionadas.end(); i++)
		{
			((Grupo*)f)->anyadirElemento(*i);
		}
		
		l = ((Grupo*)f)->getCaja().pintar();
		
		for (list<Figura*>::iterator i = l.begin(); i != l.end(); i++)
		{
			pintaFigura(*i, QColor(255,0,0), true, false);		
		}
		
		l.clear();
		
		delete f;
	}
	
	if (!pintaAccion.empty())
	{
		for (list<Figura*>::iterator i = pintaAccion.begin(); i != pintaAccion.end(); i++)
		{
			pintaFigura(*i, QColor(0,0,255), false, false);
			
			delete (*i);
		}
		
		pintaAccion.clear();		
	}
	
	l = lienzo->Pintar();
	
	if (temp != NULL)
	{
		list<Figura*>lAux = temp->pintar();
		
		l.splice(l.end(), lAux);
	}
	
	for (list<Figura*>::iterator i = l.begin(); i != l.end(); i++)
	{
		pintaFigura(*i, QColor(0,0,0), false, true);
	}
}

void
WidgetLienzoQT::pintaFigura (Figura* f, QColor color, bool caja, bool opcolor)
{
	QPainter paint(this);
	
	QPoint a, b;
	
	int tamCaja;
	
	if (caja)
	{
		tamCaja = 1;
	}
	
	else
	{
		tamCaja = 0;
	}
	
	if (opcolor)
	{
		paint.setPen(QColor(f->getCR(), f->getCG(), f->getCB()));
	}
	
	else
	{
		paint.setPen(color);
	}
	
	if (dynamic_cast<PuntoDibujo*> (f))
	{
		paint.drawPoint((f)->infDer().getX(), (f)->infDer().getY());
	}
	
	if (dynamic_cast<Linea*>(f))
	{
		a.setX(((Linea*)f)->getA().getX() + tamCaja);
		
		a.setY(((Linea*)f)->getA().getY() + tamCaja);
		
		b.setX(((Linea*)f)->getB().getX() + tamCaja);
		
		b.setY(((Linea*)f)->getB().getY() + tamCaja);
		
		paint.drawLine(a, b);
	}
	
	else if (dynamic_cast<Circulo*>(f))
	{
		Punto izSup = ((Circulo*)f)->supIzq();

		Punto derInf = ((Circulo*)f)->infDer();
		
		QPoint bottomR, topL;
		
		bottomR.setX(derInf.getX());
		
		bottomR.setY(derInf.getY());
		
		topL.setX(izSup.getX());
		
		topL.setY(izSup.getY());
		
		QRect rAux(topL, bottomR);
		
		paint.drawEllipse(rAux);
	}	
}

void 
WidgetLienzoQT::mousePressEvent( QMouseEvent *e)
{
	anterior = e->pos();
	
	if (!seleccionadas.empty() && !pinchaDentro(e))
	{
		seleccionadas.clear();
	}
};

void 
WidgetLienzoQT::mouseMoveEvent( QMouseEvent *e)
{
	QPoint actual = e -> pos();
	
	Figura* f;
	
	list<Figura*> aux;

	if (accion == poligono && finPoligono)
	{
		Punto a (temp->getPuntos().back().getX(), temp->getPuntos().back().getY());
		
		Punto b (actual.rx(), actual.ry());
		
		Punto c (temp->getPuntos().front().getX(), temp->getPuntos().front().getY());
					
		f= new Linea(a,b);
		
		pintaAccion = f->pintar();
		
		f = new Linea(b,c);
		
		aux = f->pintar();
		
		pintaAccion.splice(pintaAccion.end(), aux); 
		
		delete f;		
	}

	else if (accion == linea || accion == poligono)
	{
		Punto a (anterior.rx(), anterior.ry());
		
		Punto b (actual.rx(), actual.ry());
					
		f= new Linea(a,b);
		
		pintaAccion = f->pintar();
		
		delete f;
	}
	
	else if (accion == seleccionar)
	{
		if (seleccionadas.empty())
		{
			Punto a (anterior.rx(), anterior.ry());
			
			Punto b (actual.rx(), actual.ry());
			
			lienzo->normalizaPuntos(a,b);
			
			f= new Rectangulo(a,b);

			pintaAccion = f->pintar();
			
			delete f;			
		}
		
		else if (e->state() == Qt::RightButton)
		{
			pintaAccion.clear();
			
			for (list<Figura*>::iterator i = seleccionadas.begin(); i != seleccionadas.end(); i++)
			{
				f = (*i)->clonar();
				
				if (dynamic_cast <Rectangulo*> (f))
				{
					((Rectangulo*)f)->redimensionar2(actual.rx()-anterior.rx(), actual.ry()-anterior.ry());
				}
				
				else
				{
					f->redimensionar((actual.rx()-anterior.rx()), (actual.ry()-anterior.ry()));
				}
				
				aux = f->pintar();
				
				pintaAccion.splice(pintaAccion.end(), aux);
				
				delete f;
			}			
		}
		
		else
		{
			pintaAccion.clear();
			
			for (list<Figura*>::iterator i = seleccionadas.begin(); i != seleccionadas.end(); i++)
			{
				f = (*i)->clonar();
				
				f->trasladar((actual.rx()-anterior.rx()), (actual.ry()-anterior.ry()));
				
				aux = f->pintar();
				
				pintaAccion.splice(pintaAccion.end(), aux);
				
				delete f;
			}				
		} 
	}
	
	else if (accion == rectangulo)
	{
		Punto a (anterior.rx(), anterior.ry());
		
		Punto b (actual.rx(), actual.ry());
		
		lienzo->normalizaPuntos(a,b);
		
		f= new Rectangulo(a,b);

		pintaAccion = f->pintar();
		
		delete f;			
	}
	
	else if (accion == circulo)
	{
		Punto a (anterior.rx(), anterior.ry());
		
		Punto b (actual.rx(), actual.ry());
		
		float dif = sqrt((b.getX() - a.getX())*(b.getX() - a.getX()) + (b.getY() - a.getY())*(b.getY() - a.getY()));
		
		f = new Circulo(a, dif);
		
		pintaAccion = f->pintar();
		
		delete f;		
	}
	
	actualizar();
}

void 
WidgetLienzoQT::mouseReleaseEvent( QMouseEvent *e)
{
	QPoint actual = e -> pos();
	
	Figura* f;
	
	list<Figura*> lista ;
	
	switch (accion)
	{
		case punto: 
		{
			PuntoDibujo* p = new PuntoDibujo(Punto(anterior.rx(), anterior.ry()));
			
			p->setCR(sliderR->value());
			
			p->setCG(sliderG->value());
			
			p->setCB(sliderB->value());
			
			lienzo->anyadirFigura(p);
		}
		break;
		
		case linea: 
		{
			Punto a (anterior.rx(), anterior.ry());
			
			Punto b (actual.rx(), actual.ry());
			
			f= new Linea(a,b);
			
			f->setCR(sliderR->value());
			
			f->setCG(sliderG->value());
			
			f->setCB(sliderB->value());
			
			lienzo->anyadirFigura(f);
		}
		break;
		
		case rectangulo:
		{
			Punto a (anterior.rx(), anterior.ry());
			
			Punto b (actual.rx(), actual.ry());
			
			lienzo->normalizaPuntos(a,b);
			
			f= new Rectangulo(a,b);
			
			f->setCR(sliderR->value());
			
			f->setCG(sliderG->value());
			
			f->setCB(sliderB->value());
			
			lienzo->anyadirFigura(f);					
		}
		break;
		
		case circulo:
		{
			Punto a (anterior.rx(), anterior.ry());
			
			Punto b (actual.rx(), actual.ry());
			
			float dif = sqrt((b.getX() - a.getX())*(b.getX() - a.getX()) + (b.getY() - a.getY())*(b.getY() - a.getY()));
			
			f= new Circulo(a, dif);
			
			f->setCR(sliderR->value());
			
			f->setCG(sliderG->value());
			
			f->setCB(sliderB->value());
			
			lienzo->anyadirFigura(f);
		}
		break;
		
		case poligono:
		{
			primero = anterior;
			
			if (!finPoligono)
			{
				finPoligono = true;
				
				temp = new Poligono();
				
				temp->setCR(sliderR->value());
				
				temp->setCG(sliderG->value());
				
				temp->setCB(sliderB->value());
				
				temp->addPunto(Punto(anterior.rx(), anterior.ry()));
				
				temp->addPunto(Punto(actual.rx(), actual.ry()));
			}
			
			else
			{
				temp->addPunto(Punto(actual.rx(), actual.ry()));
			}					
		}
		break;
		
		case seleccionar:
		{	
			if (anterior == actual)
			{
				seleccionadas.clear();
				
				f = lienzo->seleccionar(anterior.rx(), anterior.ry());
				
				if (f != NULL)
				{
					seleccionadas.push_back(f);
				}
			}
			
			else
			{
				if (seleccionadas.empty())
				{
					Punto a (anterior.rx(), anterior.ry());
					
					Punto b (actual.rx(), actual.ry());
					
					lienzo->normalizaPuntos(a,b);
					
					lista = lienzo->seleccionar(a, b);
									
					seleccionadas = lista;
				}
				
				else
				{
					if (e->state() == Qt::RightButton)
					{
						lienzo->redimensionar(seleccionadas, actual.rx()-anterior.rx(), actual.ry()-anterior.ry());
					}
					
					else 
					{
						lienzo->trasladar(seleccionadas, actual.rx()-anterior.rx(), actual.ry()-anterior.ry());
					}
				}
			}
		}
		break;
	}
	
	update();
}

bool
WidgetLienzoQT::pinchaDentro(QMouseEvent *e)
{
	Grupo g;
	
	QPoint actual = e -> pos();
	
	for (list<Figura*>::iterator i = seleccionadas.begin(); i != seleccionadas.end(); i++)
	{
		g.anyadirElemento(*i);
	}
	
	return g.getCaja().seleccionar(actual.rx(), actual.ry());
}

void 
WidgetLienzoQT::cambioR(int val)
{
	r = val;
	
	QColor color = paletteBackgroundColor();
	
	color.setRgb(r, g, b);
	
	aplicarColor->setPaletteBackgroundColor(color);
}

void 
WidgetLienzoQT::cambioG(int val)
{
	g = val;
	
	QColor color = paletteBackgroundColor();
	
	color.setRgb(r, g, b);
	
	aplicarColor->setPaletteBackgroundColor(color);	
}

void 
WidgetLienzoQT::cambioB(int val)
{
	b = val;
	
	QColor color = paletteBackgroundColor();
	
	color.setRgb(r, g, b);
	
	aplicarColor->setPaletteBackgroundColor(color);	
}

MyPaint::MyPaint()
{
	wli = new WidgetLienzoQT(boxLienzo, "wli", new Lienzo());
	
	wli->setGeometry(QRect( 0, 0, 500, 500 ) );
	
	wli->setBackgroundColor( white ); 
	
	wli->setSliders(sliderR, sliderG, sliderB, botonCambiaColor);
	
	about = new About(centralWidget(),"About",  true, 0);

    connect(botonEliminar, SIGNAL( clicked() ), wli, SLOT(borraEvento()));
    
    connect(botonPegar, SIGNAL( clicked() ), wli, SLOT(pegaEvento()));
    
    connect(botonCortar, SIGNAL( clicked() ), wli, SLOT(cortaEvento()));
    
    connect(botonCopiar, SIGNAL( clicked() ), wli, SLOT(copiaEvento()));
    
    connect(botonDesagrupar, SIGNAL( clicked() ), wli, SLOT(desagrupaEvento()));
    
    connect(botonAgrupar, SIGNAL( clicked() ), wli, SLOT(agrupaEvento()));
    
    connect(botonPunto, SIGNAL( clicked() ), wli, SLOT(setAccionP()));
    
    connect(botonSeleccionar, SIGNAL( clicked() ), wli, SLOT(setAccionS()));    
    
    connect(botonRectangulo, SIGNAL( clicked() ), wli, SLOT(setAccionR()));
    
    connect(botonPoligono, SIGNAL( clicked() ), wli, SLOT(setAccionPol()));
    
    connect(botonCirculo, SIGNAL( clicked() ), wli, SLOT(setAccionC()));
    
    connect(botonLinea, SIGNAL( clicked() ), wli, SLOT(setAccionL()));	
    
    connect(botonCambiaColor, SIGNAL( clicked() ), wli, SLOT(cambiaColor()));	
    
    connect(fileNewAction, SIGNAL( activated() ), wli, SLOT(Nuevo()));
    
    connect(fileSaveAction, SIGNAL( activated() ), wli, SLOT(Guardar()));
    
    connect(fileSaveAsAction, SIGNAL( activated() ), wli, SLOT(GuardarComo()));
    
    connect(fileOpenAction, SIGNAL( activated() ), wli, SLOT(Abrir()));
    
    connect(fileExitAction, SIGNAL( activated() ), this, SLOT(quit()));
    
    connect(helpAboutAction, SIGNAL( activated() ), this, SLOT(Sobre()));
    
    connect(editUndoAction, SIGNAL( activated() ), wli, SLOT(Deshacer()));
    
    connect(editRedoAction, SIGNAL( activated() ), wli, SLOT(Rehacer()));
    
    connect(editCopyAction, SIGNAL( activated() ), wli, SLOT(copiaEvento()));
    
    connect(editCutAction, SIGNAL( activated() ), wli, SLOT(cortaEvento()));
    
    connect(editPasteAction, SIGNAL( activated() ), wli, SLOT(pegaEvento()));
    
    connect(sliderR, SIGNAL( valueChanged(int) ), wli, SLOT(cambioR(int)));
    
    connect(sliderG, SIGNAL( valueChanged(int) ), wli, SLOT(cambioG(int)));
    
    connect(sliderB, SIGNAL( valueChanged(int) ), wli, SLOT(cambioB(int)));
};
		
MyPaint::~MyPaint()
{
	delete (wli);
};
